package newsrecommendation.mediator;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.List;

import puj.news.dto.Noticia;
import puj.news.web.NewsReader;

import newsrecommendation.datamodel.NewsProduct;
import newsrecommendation.datamodel.PopularityManager;
import newsrecommendation.datamodel.keywords.NewsKeywords;
import newsrecommendation.datamodel.utils.Scores;
import newsrecommendation.datamodel.utils.UserType;
import newsrecommendation.datamodel.UserProfile;
import newsrecommendation.test.DataLoader;
import newsrecommendation.utils.StringUtils;

/**
 *
 * @author Andrea
 */
public class CommunicationMediator {
	
	private static CommunicationMediator instance;

    private List<NewsProduct> news_notObligatory;
    private List<NewsProduct> news_obligatory;
    private List<NewsProduct> available;
    private List<UserProfile> users;

    private List <Noticia>noticias;
    
    String path;
    
    
    public String getPath() {
		return path;
	}

	public void setPath(String path) {
		this.path = path;
	}

	private CommunicationMediator() {
        news_notObligatory = new ArrayList<NewsProduct>();
        news_obligatory = new ArrayList();
        available = new ArrayList();
        users = new ArrayList();
        
    }
    
    public void loadNews() throws Exception{
    	noticias=NewsReader.readNews();
    	setNews();
    }
    
    
    public static CommunicationMediator getInstance(){
    	if(instance == null){
    		instance=new CommunicationMediator();
    	}
    	return instance;
    }

    public void loadTestData() {
        DataLoader.get().loadData();
        this.users = DataLoader.get().getUsers();
    }
    
    public void loadTestData(String path) {
    	DataLoader.get().setPath(path);
        DataLoader.get().loadData();
        this.users = DataLoader.get().getUsers();
    }

    public void setNews() { //TODO - List<Noticia>
        //Set all news
    	
    	this.news_notObligatory.clear();
    	this.news_obligatory.clear();
    	
    	for(int i =0; i<noticias.size(); i++){
    		if(StringUtils.preprocess(noticias.get(i).getKeywords()).equals("Saludo del Rector")){
    			this.news_obligatory.add(noticiaToNewsProduct(noticias.get(i)));
    		}else{
    			this.news_notObligatory.add(noticiaToNewsProduct(noticias.get(i)));
    		}
    	}
    	
        //Organize by date
        Collections.sort(news_notObligatory);
        Collections.sort(news_obligatory);

        //Register to available list
        available.clear();
        available.addAll(news_notObligatory);
        available.addAll(news_obligatory);
        
        for(int i = 0; i<available.size(); i++){
        	String newsId = available.get(i).getId();
        	NewsKeywords newsKeywords = available.get(i).getKeywords();
        	Noticia n = getNoticia(newsId);
        }
        
    }

    private NewsProduct noticiaToNewsProduct(Noticia noticia){
    	NewsProduct n = new NewsProduct(noticia.getId(),noticia.getFecha(),noticia.getKeywords());
    	return n;
    }
    
    public void setUserClick(String userId, String newsId) {
        UserProfile userProfile = getUserProfile(userId);
        NewsProduct newsProduct = getNewsProduct(newsId);
        userProfile.setClickNews(newsId, newsProduct.getKeywords());
    }
    
    public boolean setUserLike(String userId, String newsId){
        UserProfile userProfile = getUserProfile(userId);
        NewsProduct newsProduct = getNewsProduct(newsId);
        userProfile.setLikeNews(newsId, newsProduct.getKeywords());
        return userProfile.isLike(newsId);
    }

    public boolean isLike(String userId, String newsId) {
        UserProfile userProfile = getUserProfile(userId);
        return userProfile.isLike(newsId);
    }

    public void setUserInterests(String userId, String csv_Keywords) {
        UserProfile userProfile = getUserProfile(userId);
        userProfile.setInterests(csv_Keywords);
    }

    public List<NewsTileResponse> getOrganizedNews(String userId) {

    	System.out.println(available.size());
    	
        List<NewsTileResponse> response = new ArrayList();
        List<String> addedResponseIds = new ArrayList();
        UserProfile userProfile = getUserProfile(userId);
        UserProfile comunidad = (new UserProfile("gh", UserType.COMUNIDAD));
        //Recalculate user scores for news
        for (NewsProduct newsProduct : available) {
            userProfile.calculateScore(newsProduct.getId(), newsProduct.getKeywords());
            comunidad.calculateScore(newsProduct.getId(), newsProduct.getKeywords());
        }

        List<String> newsIds_obligatory = getIds(news_obligatory);
        List<String> mostPopular_user = userProfile.getTopKNews(Scores.TOP_K, getIds(available)); //Calculate here to get max score       
        List<String> mostPopular_community = comunidad.getTopKNews(Scores.TOP_K, getIds(available)); //PopularityManager.get().getTopKNews(Scores.TOP_K, available);
        
        List<String> newsIds_notObligatory = getIds(news_notObligatory);

        List<String> all = new ArrayList();
        all.addAll(newsIds_obligatory);
        all.addAll(mostPopular_user);
       all.addAll(mostPopular_community);
        all.addAll(newsIds_notObligatory);

        for (String newsId : all) {
            if (!addedResponseIds.contains(newsId)) {
                NewsTileResponse n = new NewsTileResponse(newsId, userProfile.getNewsSize(newsId));
                n.setNoticia(getNoticia(newsId));
                if (mostPopular_community.contains(newsId)) {
                    n.setPopularityPosition(mostPopular_community.indexOf(newsId) + 1);
                }
                n.setIsLike(userProfile.isLike(newsId));
                response.add(n);
                addedResponseIds.add(newsId);
            }
        }

        return response;
    }

    private List<String> getIds(List<NewsProduct> news) {
        List<String> newsIds = new ArrayList();
        for (NewsProduct newsP : news) {
            newsIds.add(newsP.getId());
        }
        return newsIds;
    }

    private UserProfile getUserProfile(String userId) {
        for (UserProfile userProfile : users) {
            if (StringUtils.preprocess(userProfile.getId()).equals(StringUtils.preprocess(userId))) {
                return userProfile;
            }
        }
        return null; //TODO
    }

    private NewsProduct getNewsProduct(String newsId) {
        for (NewsProduct newsProduct : news_notObligatory) {
            if (newsProduct.getId().equals(newsId)) {
                return newsProduct;
            }
        }
        return null; //TODO
    }
    
    public Noticia getNoticia(String newsId){
    	for(int i =0; i<noticias.size(); i++){
    		if(noticias.get(i).getId().equals(newsId)){
    			return noticias.get(i);
    		}
    	}
    	return new Noticia();
    }
}
